package com.orifine.sql.chain;

import java.util.ArrayList;
import java.util.List;

import com.bowos.zmado.model.User;
import com.orifine.orm.model.ColumnModel;
import com.orifine.orm.model.TableModel;
import com.orifine.orm.spring.SqlScriptFactoryBean;
import com.orifine.orm.spring.TableScannerConfigurer;
import com.orifine.sql.SyntaxString;




public class ChainSelect implements ChainSql{
	private List<ChainAliasColumn> chainAliasColumns = new ArrayList<ChainAliasColumn>();
	
	public void column(ChainSelectColumn column, String alias){
		chainAliasColumns.add(new ChainAliasColumn(column, alias));
	}
	
	public void column(ChainSelectColumn column){
		chainAliasColumns.add(new ChainAliasColumn(column));
	}
	
	public void column(ColumnModel column, String alias){
		chainAliasColumns.add(new ChainAliasColumn(column, alias));
	}
	
	public void column(ColumnModel column){
		chainAliasColumns.add(new ChainAliasColumn(column));
	}
	
	public boolean isDistinct = false;;
	
	public ChainSelect distinct(){
		isDistinct = true;
		return this;
	}
	
	public ChainSelect distinct(boolean isDistinct){
		this.isDistinct = isDistinct;
		return this;
	}
	
	private List<String> fromTableNames = new ArrayList<String>();
	public ChainSelect from(TableModel table){
		fromTableNames.add(table.getName());
		return this;
	}
	
	private static List<ChainJoin> joins = new ArrayList<ChainJoin>();
	public ChainSelect innerJoinOn(TableModel table, ChainOn on){
		joins.add(new ChainJoin(ChainJoinType.INNER_JOIN, table, on));
		return this;
	}
	
	public ChainSelect leftJoinOn(TableModel table, ChainOn on){
		joins.add(new ChainJoin(ChainJoinType.LEFT_JOIN, table, on));
		return this;
	}
	
	public ChainSelect rightJoinOn(TableModel table, ChainOn on){
		joins.add(new ChainJoin(ChainJoinType.RIGHT_JOIN, table, on));
		return this;
	}
	
	public ChainSelect fullJoinOn(TableModel table, ChainOn on){
		joins.add(new ChainJoin(ChainJoinType.FULL_JOIN, table, on));
		return this;
	}
	
	private ChainRestrictionsElement rootRestriction;
	public ChainSelect where(ChainRestrictionsElement chainRestrictionsElement){
		rootRestriction = chainRestrictionsElement;
		return this;
	}
	
	public void chain(SyntaxString out){
		out.addWord("SELECT");
		
		if(isDistinct){
			out.addWord("DISTINCT");
		}
		
		boolean isFirst = true;
		for(ChainAliasColumn column : chainAliasColumns){
			if(isFirst){
				isFirst = false;
			} else {
				out.append(",");
			}
			column.chain(out);
		}
		
		out.addWord("FROM");
		isFirst = true;
		for(String fromTableName : fromTableNames){
			if(isFirst){
				isFirst = false;
			} else {
				out.append(",");
			}
			out.addWord(fromTableName);
		}
		
		for(ChainJoin join : joins){
			join.chain(out);
		}
		
		out.addWord("WHERE");
		rootRestriction.chain(out);
	}
	
	@Override
	public String sql() {
		SyntaxString syntaxString = new SyntaxString();
		chain(syntaxString);
		return syntaxString.toString();
	}
	
	public static void main(String[] args) throws Exception {
		SqlScriptFactoryBean sqlScriptFactoryBean = new SqlScriptFactoryBean();
		sqlScriptFactoryBean.setDatabaseName("test");
		sqlScriptFactoryBean.setInfoMaxSize(0);
		
		TableScannerConfigurer configurer = new TableScannerConfigurer();
		configurer.setBasePackage("com.bowos.zmado.model");
		configurer.setSqlScriptFactory(sqlScriptFactoryBean);
		
		sqlScriptFactoryBean.afterPropertiesSet();
		configurer.afterPropertiesSet();
		sqlScriptFactoryBean.execute();
		
		ChainSelect select = new ChainSelect();
		select.column(User.columnPassword, "user.username");
		select.column(User.columnUsername, "user.password");
		select.distinct();
		
		select.from(User.table).leftJoinOn(User.table, ChainOn.eq(User.columnUsername, User.columnPassword));
		
		select.where(new ChainRestrictions().or(ChainRestriction.eq(User.columnUsername, User.columnPassword)).or(ChainRestriction.eq(User.columnUsername, User.columnPassword)));
		System.out.println(select.sql());
	}
}
